//
//  @ Project : Galaxy Star Trading System
//  @ File Name : CommissionRate.cpp
//  @ Date : 2014/9/5
//  @ Author :
//
//

#include "../StdInc.h"

namespace GSTrader
{
	namespace TradeBase
	{
		CCommissionRate::CCommissionRate() : m_dBuyOpenRatioByMoney(0), m_dBuyOpenRatioByVolume(0), m_strInstrumentId(""),
			m_strExchangeId(""), m_dBuyCloseRatioByMoney(0), m_dBuyCloseRatioByVolume(0), m_dBuyCloseTodayRatioByMoney(0), m_dBuyCloseTodayRatioByVolume(0),
			m_dBuyReserve1(0), m_dBuyReserve2(0), m_dSellCloseRatioByMoney(0), m_dSellCloseRatioByVolume(0), m_dSellCloseTodayRatioByMoney(0),
			m_dSellCloseTodayRatioByVolume(0), m_dSellReserve1(0), m_dSellReserve2(0), m_dSellOpenRatioByMoney(0), m_dSellOpenRatioByVolume(0), m_nProviderId(-1)
		{

		}

		CCommissionRate::~CCommissionRate()
		{

		}

		CCommissionRate::CCommissionRate(const CCommissionRate& r)
		{
			m_strInstrumentId = r.m_strInstrumentId;
			m_strExchangeId = r.m_strExchangeId;

			m_dBuyOpenRatioByMoney = r.m_dBuyOpenRatioByMoney;
			m_dBuyOpenRatioByVolume = r.m_dBuyOpenRatioByVolume;
			m_dBuyCloseRatioByMoney = r.m_dBuyCloseRatioByMoney;
			m_dBuyCloseRatioByVolume = r.m_dBuyCloseRatioByVolume;
			m_dBuyCloseTodayRatioByMoney = r.m_dBuyCloseTodayRatioByMoney;
			m_dBuyCloseTodayRatioByVolume = r.m_dBuyCloseTodayRatioByVolume;

			m_dBuyReserve1 = r.m_dBuyReserve1;
			m_dBuyReserve2 = r.m_dBuyReserve2;

			m_dSellOpenRatioByMoney = r.m_dSellOpenRatioByMoney;
			m_dSellOpenRatioByVolume = r.m_dSellOpenRatioByVolume;
			m_dSellCloseRatioByMoney = r.m_dSellCloseRatioByMoney;
			m_dSellCloseRatioByVolume = r.m_dSellCloseRatioByVolume;
			m_dSellCloseTodayRatioByMoney = r.m_dSellCloseTodayRatioByMoney;
			m_dSellCloseTodayRatioByVolume = r.m_dSellCloseTodayRatioByVolume;

			m_dSellReserve1 = r.m_dSellReserve1;
			m_dSellReserve2 = r.m_dSellReserve2;
		}

		bool CCommissionRate::HaveBuyData()
		{
			if (m_dBuyOpenRatioByMoney > DBL_MIN)
				return true;
			if (m_dBuyOpenRatioByVolume > DBL_MIN)
				return true;

			return m_dBuyCloseRatioByMoney > DBL_MIN ||	m_dBuyCloseRatioByVolume > DBL_MIN || m_dBuyCloseTodayRatioByMoney > DBL_MIN ||
			       m_dBuyCloseTodayRatioByVolume > DBL_MIN;
		}

		bool CCommissionRate::HaveSellData()
		{
			if (m_dSellOpenRatioByMoney > DBL_MIN)
				return true;
			if (m_dSellOpenRatioByVolume > DBL_MIN)
				return true;

			return m_dSellCloseRatioByMoney > DBL_MIN || m_dSellCloseRatioByVolume > DBL_MIN || m_dSellCloseTodayRatioByMoney > DBL_MIN ||
			       m_dSellCloseTodayRatioByVolume > DBL_MIN;
		}

		bool CCommissionRate::BuyCalcByMoney()
		{
			if (m_dBuyOpenRatioByMoney > DBL_MIN)
				return true;
			if (m_dBuyOpenRatioByVolume > DBL_MIN)
				return false;
			if (m_dBuyCloseRatioByMoney > DBL_MIN)
				return true;
			if (m_dBuyCloseRatioByVolume > DBL_MIN)
				return false;
			if (m_dBuyCloseTodayRatioByMoney > DBL_MIN)
				return true;
			if (m_dBuyCloseTodayRatioByVolume > DBL_MIN)
				return false;

			return false;
		}

		bool CCommissionRate::SellCalcByMoney()
		{
			if (m_dSellOpenRatioByMoney > DBL_MIN)
				return true;
			if (m_dSellOpenRatioByVolume > DBL_MIN)
				return false;
			if (m_dSellCloseRatioByMoney > DBL_MIN)
				return true;
			if (m_dSellCloseRatioByVolume > DBL_MIN)
				return false;
			if (m_dSellCloseTodayRatioByMoney > DBL_MIN)
				return true;
			if (m_dSellCloseTodayRatioByVolume > DBL_MIN)
				return false;

			return false;
		}

		double CCommissionRate::GetCommissionRateByVol(int nOffset)
		{
			if (nOffset == ocOpen)
			{
				return m_dBuyOpenRatioByVolume;
			}
			else if (nOffset == ocCloseToday)
			{
				return m_dBuyCloseTodayRatioByVolume;
			}
			else if (nOffset == ocClose || nOffset == ocForceClose)
			{
				return m_dBuyCloseRatioByVolume;
			}
			else if (nOffset == ocCloseYesterday)
			{
				return m_dBuyCloseRatioByVolume;
			}

			assert(false);
			return 0;
		}

		double CCommissionRate::GetCommissionRateByMoney(int nOffset)
		{
			if (nOffset == ocOpen)
			{
				return m_dBuyOpenRatioByMoney;
			}
			else if (nOffset == ocCloseToday)
			{
				return m_dBuyCloseTodayRatioByMoney;
			}
			else if (nOffset == ocClose || nOffset == ocForceClose)
			{
				return m_dBuyCloseRatioByMoney;
			}
			else if (nOffset == ocCloseYesterday)
			{
				return m_dBuyCloseRatioByMoney;
			}

			assert(false);
			return 0;
		}

		double CCommissionRate::GetStampTaxRateByMoney(int nDirection)
		{
			if (nDirection == ocOpen)
				return m_dBuyOpenRatioByMoney;
			else
				return m_dSellOpenRatioByMoney;
		}

		double CCommissionRate::GetStampTaxRateByVolume(int nDirection)
		{
			if (nDirection == ocOpen)
				return m_dBuyOpenRatioByVolume;
			else
				return m_dSellOpenRatioByVolume;
		}

		double CCommissionRate::GetTransferFeeRateByMoney(int nDirection)
		{
			if (nDirection == ocOpen)
				return m_dBuyCloseRatioByMoney;
			else
				return m_dSellCloseRatioByMoney;
		}

		double CCommissionRate::GetTransferFeeRateByVolume(int nDirection)
		{
			if (nDirection == ocOpen)
				return m_dBuyCloseRatioByVolume;
			else
				return m_dSellCloseRatioByVolume;
		}

		double CCommissionRate::GetTradeFeeByMoney(int nDirection)
		{
			if (nDirection == ocOpen)
				return m_dBuyCloseTodayRatioByMoney;
			else
				return m_dSellCloseTodayRatioByMoney;
		}

		double CCommissionRate::GetTradeFeeByVolume(int nDirection)
		{
			if (nDirection == ocOpen)
				return m_dBuyCloseTodayRatioByVolume;
			else
				return m_dSellCloseTodayRatioByVolume;
		}

		double CCommissionRate::GetMarginByMoney(int nDirection)
		{
			if (nDirection == ocOpen)
				return m_dBuyReserve1;
			else
				return m_dSellReserve1;
		}

		double CCommissionRate::GetMinTradeFee(int nDirection)
		{
			if (nDirection == ocOpen)
				return m_dBuyReserve2;
			else
				return m_dSellReserve2;
		}

		void CCommissionRate::Serialize(CArchiveEx& ar)
		{
			if (ar.IsStore())
			{
				ar << m_strInstrumentId;
				ar << m_strExchangeId;
				ar << m_dBuyOpenRatioByMoney;
				ar << m_dBuyOpenRatioByVolume;
				ar << m_dBuyCloseRatioByMoney;
				ar << m_dBuyCloseRatioByVolume;
				ar << m_dBuyCloseTodayRatioByMoney;
				ar << m_dBuyCloseTodayRatioByVolume;
				ar << m_dBuyReserve1;
				ar << m_dBuyReserve2;

				ar << m_dSellOpenRatioByMoney;
				ar << m_dSellOpenRatioByVolume;
				ar << m_dSellCloseRatioByMoney;
				ar << m_dSellCloseRatioByVolume;
				ar << m_dSellCloseTodayRatioByMoney;
				ar << m_dSellCloseTodayRatioByVolume;
				ar << m_dSellReserve1;
				ar << m_dSellReserve2;
			}
			else
			{
				ar >> m_strInstrumentId;
				ar >> m_strExchangeId;
				ar >> m_dBuyOpenRatioByMoney;
				ar >> m_dBuyOpenRatioByVolume;
				ar >> m_dBuyCloseRatioByMoney;
				ar >> m_dBuyCloseRatioByVolume;
				ar >> m_dBuyCloseTodayRatioByMoney;
				ar >> m_dBuyCloseTodayRatioByVolume;
				ar >> m_dBuyReserve1;
				ar >> m_dBuyReserve2;

				ar >> m_dSellOpenRatioByMoney;
				ar >> m_dSellOpenRatioByVolume;
				ar >> m_dSellCloseRatioByMoney;
				ar >> m_dSellCloseRatioByVolume;
				ar >> m_dSellCloseTodayRatioByMoney;
				ar >> m_dSellCloseTodayRatioByVolume;
				ar >> m_dSellReserve1;
				ar >> m_dSellReserve2;
			}
		}
	}
}